<?php

namespace App\Kuafu\Order\Service;

use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Common\Service\EncryptService;
use App\Kuafu\Invoice\Enum\InvoiceCodeEnum;
use App\Kuafu\Invoice\Exceptions\InvoiceException;
use App\Kuafu\Order\Enum\CodeEnum;
use App\Kuafu\Order\Model\OrderInvoiceModel;
use App\Kuafu\Order\Model\OrderSplitModel;
use App\Kuafu\WaiMai\Model\WaiMaiOrderModel;
use App\Kuafu\WaiMai\Service\WaiMaiOrderService;
use Illuminate\Support\Facades\Log;

class OrderInvoiceService extends BaseService
{

    /**
     * 对外发票信息状态
     *
     * @param $dbInvoiceStatus int 状态
     * @param $createdAt int 创建时间
     * @return int
     */
    public static function orderInvoiceStatus(
        $dbInvoiceStatus,
        int $createdAt = 0,
        int $invoiceCanCancelCount = 99
    ): int {

        $validTime = $createdAt + CodeEnum::ORDER_OUT_INVOICE_EXP_TIME * 86400;

        if ($validTime < time()) {
            return CodeEnum::ORDER_OUT_INVOICE_STATUS_CANNOT_CREATE;
        }

        if ($invoiceCanCancelCount <= 0 && $dbInvoiceStatus == CodeEnum::ORDER_INVOICE_STATUS_HAVEN) {
            return CodeEnum::ORDER_OUT_INVOICE_STATUS_BANNED_CANCELED;
        }

        switch ($dbInvoiceStatus) {
            case CodeEnum::ORDER_INVOICE_STATUS_DEFAULT:
            case CodeEnum::ORDER_INVOICE_STATUS_WAIT:
                return CodeEnum::ORDER_OUT_INVOICE_STATUS_DEFAULT;
            case CodeEnum::ORDER_INVOICE_STATUS_HAVEN:
                return CodeEnum::ORDER_OUT_INVOICE_STATUS_HAVEN;
            case CodeEnum::ORDER_INVOICE_STATUS_CANCELING:
                return CodeEnum::ORDER_OUT_INVOICE_STATUS_CANCELING;
            case CodeEnum::ORDER_INVOICE_STATUS_CANCELED:
            case CodeEnum::ORDER_INVOICE_STATUS_RED_CANCELED:
                return CodeEnum::ORDER_OUT_INVOICE_STATUS_CANCELED;
            default:
                return CodeEnum::ORDER_OUT_INVOICE_STATUS_DEFAULT;
        }
    }

    /**
     * 返回 订单的 开票地址
     *
     * @param $orderId
     * @param $dbInvoiceStatus
     * @param $orderSource string 订单来源 1 堂食 2 外卖
     * @return string
     */
    public static function genOrderInvoiceUrl(
        $orderId,
        $dbInvoiceStatus,
        $shopId,
        $orderSource = CodeEnum::SOURCE_TYPE_SHOP
    ): string {
        $outSide = config('app.outSideUrl') . '/i/';
        if ($dbInvoiceStatus == CodeEnum::ORDER_INVOICE_STATUS_WAIT) {
            return $outSide . urlencode(EncryptService::encryptOrderId(self::encOrderId($orderId, $orderSource,
                    $shopId)));
        } else {
            return '';
        }
    }

    /**
     * 添加发票记录
     * @param $data
     */
    public static function addInvoiceData($data)
    {
        try {
            OrderInvoiceModel::addData($data);
        } catch (\Exception $exception) {
            Log::channel('invoice')->info("盟度开票回调信息-入库失败:" . $exception->getMessage());
            throw new InvoiceException(InvoiceCodeEnum::ERR_INSERT);
        }
    }

    /**
     * @param string $orderId
     * @param string $shopId
     * @param int $status
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Support\Traits\Conditionable|mixed|object|null
     */
    public static function getInvoiceInfoById(string $orderId, string $shopId, int $status = 0)
    {
        return OrderInvoiceModel::query()
                                ->where('orderId', $orderId)
                                ->where('shopId', $shopId)
                                ->when($status, function ($query) use ($status) {
                                    $query->where('status', $status);
                                })
                                ->orderBy('id', 'desc')
                                ->first();
    }

    /**
     * 根据订单id修改有效订单数据
     * @param $id
     * @param $field
     */
    public static function updateFieldByOrderId($id, $field)
    {
        OrderInvoiceModel::query()
                         ->where('id', $id)
                         ->update($field);
    }

    /**
     * 解析订单id
     * @param $orderId
     * @return array
     */
    public static function getInvoiceType($orderId): array
    {
        Log::channel('invoice')->info('盟度回调订单号：' . $orderId);
        $data = explode('-', $orderId);
        if (count($data) > 1) {
            $type = OrderInvoiceModel::ORDER_INVOICE_DB_ORDER_TYPE_POS;
            if ($data[0] == OrderInvoiceModel::ORDER_TYPE_TAKE_OUT) {
                $type = OrderInvoiceModel::ORDER_INVOICE_DB_ORDER_TYPE_WAIMAI;
            } elseif ($data[0] == OrderInvoiceModel::ORDER_TYPE_HALL) {
                $type = OrderInvoiceModel::ORDER_INVOICE_DB_ORDER_TYPE_POS;
            }
            return [
                'type'    => $type,
                'shopId'  => $data[1] ?? 0,
                'orderId' => $data[2] ?? 0
            ];
        } else {
            throw new InvoiceException(InvoiceCodeEnum::ERR_GET_ENCRYPT);
        }
    }

    public static function redCallbackModifyOrder($orderId)
    {
        try {
            $orderId   = str_replace(OrderInvoiceModel::ORDER_CALLBACK_RED, '', $orderId);
            $orderType = OrderInvoiceService::getInvoiceType($orderId);
            $info      = OrderInvoiceService::getInvoiceInfoById($orderType['orderId'], $orderType['shopId']);
            if (empty($info)) {
                throw new InvoiceException(InvoiceCodeEnum::ERR_NO_ORDER);
            }
            if ($info['status'] == OrderInvoiceModel::ORDER_INVOICE_STATUS_VALID) {
                //如果是红冲回到并且是有效状态 修改数据库状态
                $field = ['status' => OrderInvoiceModel::ORDER_INVOICE_STATUS_RED_CANCELED];
                OrderInvoiceService::updateFieldByOrderId($info['id'], $field);
                Log::channel('invoice')->info("盟度开票回调信息-红冲修改:" . $orderType['orderId']);
            }
        } catch (\Exception $exception) {
            Log::channel('invoice')->info("盟度开票回调信息-红冲回调修改失败:" . $orderId . '----' . $exception->getMessage());
            throw new InvoiceException(\App\Kuafu\Invoice\Enum\InvoiceCodeEnum::ERR_RED_INVOICE_CALLBACK);
        }
    }

    public static function callbackInsertInvoice($orderId, $shopId, $dataArr)
    {
        Log::channel('invoice')->info('盟度开票进入：' . $orderId . '---' . $shopId . '---' . json_encode($dataArr));
        try {
            $infoById = OrderInvoiceService::getInvoiceInfoById($orderId, $shopId,
                OrderInvoiceModel::ORDER_INVOICE_STATUS_APPLY);
            if (!empty($infoById)) {
                $invoiceData = $dataArr['REQUEST_COMMON_FPKJ']['COMMON_FPKJ_FPT'];
                $updateData  = [
                    'jshj'   => $invoiceData['JSHJ'],
                    'hjje'   => $invoiceData['HJJE'],
                    'hjse'   => $invoiceData['HJSE'],
                    'fpdm'   => $invoiceData['FPDM'],
                    'fphm'   => $invoiceData['FPHM'],
                    'fplxdm' => $invoiceData['FPLXDM'],
                    'status' => OrderInvoiceModel::ORDER_INVOICE_STATUS_VALID
                ];
                Log::channel('invoice')->info("盟度开票回调信息-更新开票回调数据:" . json_encode($updateData, JSON_UNESCAPED_UNICODE));
                OrderInvoiceService::updateFieldByOrderId($infoById['id'], $updateData);
                // 更新开票状态
                self::InvoiceStatusUpdate($orderId, $shopId, $infoById['orderType'],
                    CodeEnum::ORDER_INVOICE_STATUS_HAVEN);

            }
        } catch (\Exception $exception) {
            Log::channel('invoice')->info("盟度开票回调信息-新增数据失败:" . $orderId . '-----' . $exception->getMessage());
            throw new InvoiceException(\App\Kuafu\Invoice\Enum\InvoiceCodeEnum::ERR_INSERT);
        }
    }

    /**
     * 根据订单类型获取更新订单状态
     *
     * @param $orderId
     * @param $shopId
     * @param $type
     * @return array|mixed
     * @throws \App\Kuafu\WaiMai\Exceptions\WaiMaiException
     */
    public static function genInvoiceInfo($orderId, $shopId, $type)
    {
        /**
         * 更新状态
         */
        self::InvoiceStatusUpdate($orderId, $shopId, $type);

        $info = self::getOrderInfo($orderId, $shopId, $type);

        return $info;
    }

    public static function getOrderInfo($orderId, $shopId, $type)
    {
        // 门店堂食订单信息
        if ($type == CodeEnum::SOURCE_TYPE_SHOP) {
            // 更新 订单的开票信息
            $info = OrderService::getOrderByIdAfterChange($shopId, $orderId);
        } else {
            $info = WaiMaiOrderService::orderDetail($orderId);
        }

        return $info;
    }

    /**
     * 更新数据库状态
     *
     * @param $orderId
     * @param $shopId
     * @param $type
     * @param int $status
     */
    public static function InvoiceStatusUpdate($orderId, $shopId, $type, $status = CodeEnum::ORDER_INVOICE_STATUS_WAIT)
    {
        // 门店堂食订单信息
        if ($type == CodeEnum::SOURCE_TYPE_SHOP) {
            // 更新 订单的开票信息
            OrderSplitModel::suffix($shopId)->invoiceStatusUpdate($orderId, $status);
        } else {
            WaiMaiOrderModel::invoiceStatusUpdate($orderId, $shopId, $status);
        }
    }

    /**
     * 更新数据库状态
     *
     * @param $orderId
     * @param $shopId
     * @param $type
     * @param int $status
     */
    public static function reduceOrderInvoiceCount($orderId, $shopId, $type)
    {
        // 门店堂食订单信息
        if ($type == CodeEnum::SOURCE_TYPE_SHOP) {
            // 更新 订单的开票信息
            OrderSplitModel::suffix($shopId)->reduceInvoiceCancelCount($orderId);
        } else {
            WaiMaiOrderModel::reduceInvoiceCancelCount($orderId, $shopId);
        }
    }


    /**
     * 生成订单
     *
     * @param $orderId
     * @param $orderSource
     * @param $shopId
     * @return string
     */
    public static function encOrderId($orderId, $orderSource, $shopId)
    {
        $orderIdArr = [];
        if ($orderSource == CodeEnum::SOURCE_TYPE_SHOP) {
            $orderIdArr[0] = OrderInvoiceModel::ORDER_TYPE_HALL;
        } else {
            $orderIdArr[0] = OrderInvoiceModel::ORDER_TYPE_TAKE_OUT;
        }

        $orderIdArr[1] = $shopId;
        $orderIdArr[2] = $orderId;

        return implode('-', $orderIdArr);

    }

}
